import { defineStore } from 'pinia';
import { watch } from 'vue';
import { mitt, setupWebSocket, getSystemConfig, trim, isEmpty } from '@jecloud/utils';
import { useAdminStore } from './admin-store';
import { Modal } from '@jecloud/ui';
import { useDebugger } from '@/helper/mixin-je';
/**
 * websocket
 */
export const useWebSocketStore = defineStore({
  id: 'websocket-store',
  state: () => ({
    emitter: mitt(),
    message: null, // 最新消息
    websocket: null, // socket实例
    disabled: false, // 禁用
    watchs: [], // 脚本监听函数
    notices: [], // 消息的store
  }),
  actions: {
    /**
     * 绑定事件
     * @param args
     */
    on(...args) {
      this.emitter.on(...args);
    },
    /**
     * 触发事件
     * @param args
     */
    emit(...args) {
      return this.emitter.emit(...args);
    },
    /**
     * 安装websocket
     * @param {*} options
     */
    setupWebSocket(options) {
      if (!this.disabled) {
        this.websocket = setupWebSocket({
          url: this.getWebSocketUrl(),
          debug: this.debug,
          ...options,
        });
        // 启用调试
        const debug = useDebugger();
        watch(
          () => debug.value,
          () => {
            this.websocket.enableDebugger(debug.value);
          },
        );
      }
    },
    /**
     * 获取websocket配置地址
     * @returns url
     */
    getWebSocketUrl() {
      const wsPrefix = window.location.href.startsWith('https') ? 'wss' : 'ws';
      let baseUrl = `${wsPrefix}://${window.location.host}/jesocket`;
      return trim(getSystemConfig('JE_CORE_WEBSOCKETURL')) || baseUrl;
    },
    /**
     * 登录
     */
    login() {
      this.websocket?.connect(this.getWebSocketUrl());
    },
    /**
     * 退出
     */
    logout() {
      this.websocket?.close();
      // 清空监听事件
      this.emitter.clear();
      // 清空监听函数
      this.watchs.forEach((fn) => {
        fn?.();
      });
      this.watchs = [];
      // 销毁通知框
      Modal.notification.destroy();
    },
    /**
     * 接收事件
     * @param {*} message
     */
    onMessage(message) {
      const adminStore = useAdminStore();
      this.message = message;
      this.emit('message', message);
      // 触发子应用
      adminStore.emitMicroAll('websocket-message', message);
    },
    /**
     * 添加监听事件，脚本中使用
     * @param {*} watchFn
     */
    addWatch(watchFn) {
      const fn = watch(() => this.message, watchFn);
      this.watchs.push(fn);
      return fn;
    },
  },
});
